import { Injectable } from '@nestjs/common';
import * as puppeteer from 'puppeteer';
import { ICrawler, NovelInfo, ChapterInfo, ChapterContent } from './interfaces/crawler.interface';

@Injectable()
export class QidianCrawler implements ICrawler {
  private browser: puppeteer.Browser;

  async initBrowser() {
    if (!this.browser) {
      const executablePath = process.env.CHROME_EXECUTABLE_PATH ||
        'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe';

      this.browser = await puppeteer.launch({
        headless: 'new',
        executablePath,
        args: ['--no-sandbox', '--disable-setuid-sandbox'],
      });
    }
  }

  getSource(): string {
    return 'qidian';
  }

  validateUrl(url: string): boolean {
    return url.includes('qidian.com') && url.includes('/book/');
  }

  async getNovelInfo(url: string): Promise<NovelInfo> {
    await this.initBrowser();
    const page = await this.browser.newPage();

    try {
      await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36');
      await page.goto(url, { waitUntil: 'networkidle2' });

      const novelInfo = await page.evaluate(() => {
        const title = document.querySelector('.book-info .book-name')?.textContent?.trim() || '';
        const author = document.querySelector('.book-info .author .name')?.textContent?.trim() || '';
        const cover = document.querySelector('.book-img img')?.getAttribute('src') || '';
        const description = document.querySelector('.book-intro .intro')?.textContent?.trim() || '';
        const category = document.querySelector('.book-info .book-tag .tag')?.textContent?.trim() || '';
        const statusText = document.querySelector('.book-info .book-state .tag')?.textContent?.trim() || '';
        const status = statusText.includes('完结') ? 1 : 0;

        // 获取章节列表
        const chapterElements = document.querySelectorAll('.volume-wrap .cf li a');
        const chapters: ChapterInfo[] = [];

        chapterElements.forEach((element, index) => {
          const title = element.textContent?.trim() || '';
          const href = element.getAttribute('href') || '';
          if (title && href) {
            chapters.push({
              title,
              url: `https:${href}`,
              index: index + 1,
            });
          }
        });

        return {
          title,
          author,
          cover,
          description,
          category,
          status,
          chapterList: chapters,
        };
      });

      return novelInfo;
    } finally {
      await page.close();
    }
  }

  async getChapterContent(chapterUrl: string): Promise<ChapterContent> {
    await this.initBrowser();
    const page = await this.browser.newPage();

    try {
      await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36');
      await page.goto(chapterUrl, { waitUntil: 'networkidle2' });

      const chapterContent = await page.evaluate(() => {
        const title = document.querySelector('.text-wrap .main-text-wrap h1')?.textContent?.trim() || '';
        const contentElement = document.querySelector('.text-wrap .read-content');
        const content = contentElement?.textContent?.trim() || '';

        return {
          title,
          content,
          index: 0, // 由调用方设置
        };
      });

      return chapterContent;
    } finally {
      await page.close();
    }
  }

  async onModuleDestroy() {
    if (this.browser) {
      await this.browser.close();
    }
  }
}